#!/bin/bash

# What this script does:
# First, create aliases for release and debug version of hms.
# To this end:
    # get the paths to the executables
    # find out which shell is the default
    # try to find the correct file to put the aliases in
    # check the file for existing aliases
    # delete old aliases or exit
    # create new aliases
# Then, it registers the command completion file.

set -eu

buildtypes=${1:-0}
createalias=${2:-0}
enablecompl=${3:-0}
buildshorthand=${4:-0}

# script path
sd="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

hmsdir="$(dirname -- ${sd})"

scdir="${hmsdir}/scripts"
sf="${scdir}/shared_funcs.sh"

if [ -f "$sf" ]; then
    source "$sf"
else
    echo "Script file not found: $sf"
    echo "Exiting..."
    exit
fi

# get default shell
defsh="$(basename -- "${SHELL}")"
echo "Found default shell: ${defsh}"

rcfile="$HOME/.${defsh}rc"
# echo "${rcfile}"

if [ ! -f "${rcfile}" ]; then
    echo "No run control file found!"
    echo "Cannot register hms aliases or command completion."
    exit
fi


function escape_slash () {
    sed 's~/~\\/~g' <<< "$1"
}

function delete_between () {
    local pbeg="$1"
    local pend="$2"
    local writefile="$3"
    # escape slashes in patterns for sed
    local pbeg_e=$(escape_slash "$pbeg")
    local pend_e=$(escape_slash "$pend")
    # find beginning and end pattern, add indent and print
    sed 's/^/  /' <<< \
    $(sed -n '/'"${pbeg_e}"'/,${p;/'"$pend_e"'/q}' "${writefile}")
    echo "Overwriting..."
    # find first line to start deleting, i.e. the condition
    linebeg=$( grep -n -m 1 "${pbeg}" "${writefile}" | cut -f1 -d: )
    # don't overwrite backups, otherwise they're useless.
    local ext=".bak"
    if [ -f "${writefile}${ext}" ]; then ext=""; fi
    # now delete until the end pattern
    sed -i"$ext" "$linebeg"',/'"${pend_e}"'$/d' "${writefile}"
}

function overwrite_registration () {
    local writefile="$1"
    local regfilename="$2"
    local regfile="$3"
    local comment="$4"
    # look for the file name (without path), and if it exists,
    # delete both the comment and the condition
    if grep -q "if .*${regfilename}" "${writefile}"; then
        echo "Existing registration found in ${writefile}"
        delete_between "^if .*${regfilename}" "^fi" "${writefile}"
        # delete comment separately, because it may not be there.
        sed -i '/'"$(escape_slash "$comment")"'/d' "${writefile}"
    else
        echo "" >> "${writefile}"
    fi

    echo -e "Registering file\n  ${regfile}\nin\n  ${writefile}"
    echo "${comment}" >> ${writefile}
    echo "if [ -f ${regfile} ]; then" >> ${writefile}
    echo -e "    . ${regfile}\nfi" >> ${writefile}
}

# file to hold the relevant commands
cfname="hms-commands.sh"
commandfile="${scdir}/${cfname}"
# and a comment for explanation
rccomment="# aliases and/or commands for hms"

# make run control file source hms' command file
if (( $createalias == 1 )) && (( $enablecompl == 1 )); then
    echo "No alias or command completion chosen"
    exit
else
    echo "Registering command file in run control file..."
    echo "Using run control file: ${rcfile}"
    overwrite_registration \
        "${rcfile}" "${cfname}" "${commandfile}" "${rccomment}"
    echo ""
fi

# start subshell to allow "exit" command
( if (( createalias == 0 )); then
#     echo "Using run control file: ${rcfile}"
    echo "Creating aliases..."
    echo "Using command file: ${commandfile}"

    # create a comment in the file to make it easier to identify later
    aliascomment="# aliases for hms:"
    aliasstem="alias hms"

    # check whether aliases already exist, including the comment.
    # due to problems with the script exiting when grep doesn't find anything,
    # we need to execute grep twice.
    function grep_alias() {
        grep $1 "${aliasstem}\|${aliascomment}" "${commandfile}"
    }

    if grep_alias -q; then
        sed -i "/${aliascomment}/d" "${commandfile}"
        sed -i "/${aliasstem}/d" "${commandfile}"
    fi

    echo "${aliascomment}" >> "${commandfile}"

    if (( $buildtypes <= 1 )); then
        echo "Adding alias for release executable:"
        alias_rel="${aliasstem}='${hmspath_rel}'"
        echo "  ${alias_rel}"
        echo "${alias_rel}" >> "${commandfile}"
    fi

    if (( $buildtypes >= 1 )); then
        echo "Adding alias for debug executable:"
        alias_deb="${aliasstem}db='${hmspath_deb}'"
        echo "  ${alias_deb}"
        echo "${alias_deb}" >> "${commandfile}"
    fi

    echo "" >> "${commandfile}"
    echo "Finished creating aliases."
    echo ""
fi )

( if (( $enablecompl == 0 )); then
#     echo "Using run control file: ${rcfile}"
    echo "Registering command completion for hms..."
    echo "Using command file: ${commandfile}"

    complfilename="hms-completion.bash"
    complfile="${scdir}/${complfilename}"
    complcomment="# argument completion for hms:"

    if [ ! -f "${complfile}" ]; then
        echo "Completion file not found: ${complfile}"
        echo "Exiting..."
        exit
    fi

    overwrite_registration \
        "${commandfile}" "${complfilename}" "${complfile}" "${complcomment}"

    echo "" >> "${commandfile}"
    echo "Finished registering completion file."
    echo ""
fi )

( if (( $buildshorthand == 0 )); then
    echo "Using command file: ${commandfile}"

    # check for existing functions and delete them
    fdecl1="function buildhms"
    fdecl2="function __buildhms_completion"

    function delete_func () {
        local fdecl="$1"
        if grep -q "$fdecl" "${commandfile}"; then
            echo "Existing function for build shorthands found in ${commandfile}"
            delete_between "$fdecl" "}" "${commandfile}"
        fi
    }
    delete_func "$fdecl1"
    delete_func "$fdecl2"

    # actual call to "complete"
    sed -i '/complete.*buildhms/d' "${commandfile}"

    # append raw build functions file to command file,
    # then modify it to account for build configuration
    buildfuncf="${scdir}/buildhms_raw"
    if [ -f "${buildfuncf}" ]; then
        cat "${buildfuncf}" >> "${commandfile}"
    else
        echo "File not found: ${buildfuncf}"
        echo "Exiting..."
        exit
    fi

    function add_to_line () {
        local find="$(escape_slash "$1")"
        local add="$(escape_slash "$2")"
        sed -i 's/'"${find}"'.*/'"${find}${add}"'/' "${commandfile}"
    }

    p1="local builddir="
    p2="local np="

    add_to_line "${p1}" "\"${hmsdir}/build\""
    add_to_line "${p2}" "$(get_n_threads_build)"

    function delete_build_type () {
        sed -i '/local '"$1"'=\|$'"$1"'\|"all")/d' "${commandfile}"
    }

    if (( $buildtypes == 0 )); then # only release
        # delete all lines pertaining to debug mode
        delete_build_type "deb"
        compl_words="Release"
    elif (( $buildtypes == 2 )); then # only debug
        # delete all lines pertaining to debug mode
        delete_build_type "rel"
        compl_words="Debug"
    else # Release and Debug
        compl_words="all Debug Release"
    fi
    add_to_line "local options=" "\"${compl_words}\""
#     echo -e "complete -W \"$compl_words\" buildhms\n" >> "${commandfile}"
fi )

echo "Finished registering hms."
